package com.amtf.datafile2.cfg.std;

import java.io.File;
import java.io.StringReader;
import java.util.HashMap;
import java.util.Map;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;

public abstract class StdDefinitionStore<T extends StdDefinition> {
	private final Map<String, StdDefinition> configMap = new HashMap<String, StdDefinition>();

	// public abstract DefinitionStore<T> loadConfig() throws DefinitionException;
	// public abstract DefinitionStore<T> loadConfig(File defineFile) throws DefinitionException;

	// public static StdDefinitionStore loadConfig(StdDefinitionStore instance) throws StdDefinitionException {
	// File[] files = instance.getDefaultConfigFiles();
	// if (files != null && files.length != 0) {
	// for (File file : files) {
	// loadConfig(instance, file.getPath());
	// }
	// } else {
	// throw new StdDefinitionException("Default config file not set");
	// }
	//
	// return instance;
	// }

	// protected abstract File[] getDefaultConfigFiles();

	public static StdDefinitionStore loadConfig(StdDefinitionStore instance, String defineFile) throws StdDefinitionException {
		try {
			Document doc = (Document) loadDocument(defineFile);

			instance.parse(doc, doc.getRootElement());
		} catch (Exception e) {
			// e.printStackTrace();
			throw new StdDefinitionException(e);
		}

		return instance;
	}

	public static Document loadDocument(String defineFile) throws StdDefinitionException {
		Document doc = null;
		SAXBuilder builder = new SAXBuilder(false);
		builder.setEntityResolver(new EntityResolver() {
			public InputSource resolveEntity(String publicId, String systemId) {
				return new InputSource(new StringReader(""));
			}
		});
		try {
			doc = (Document) builder.build(new File(defineFile));
		} catch (Exception e) {
			// e.printStackTrace();
			throw new StdDefinitionException(e);
		}

		return doc;
	}

	public T getConfiguration(String name) {
		return (T) configMap.get(name);
	}

	// public T getConfigInfo(String name) {
	// Collection c = configMap.values();
	// for
	// }

	// public void setConfigInfo(String name, ConfigInfo info) {
	// configMap.put(name, info);
	// }

	public void addConfiguration(StdDefinition info) {
		configMap.put(info.getName(), info);
	}

	public void removeConfiguration(String name) {
		configMap.remove(name);
	}

	public void clearConfiguration() {
		configMap.clear();
	}

	public abstract T parse(Document doc, Element root) throws StdDefinitionException;
}
